Skip to content

feat(util-retry): support AbortSignal in DefaultRateLimiter.getSendToken#1887

Open
TrevorBurnham wants to merge 1 commit intosmithy-lang:mainfrom
TrevorBurnham:fix/rate-limiter-abort-signal
Open

feat(util-retry): support AbortSignal in DefaultRateLimiter.getSendToken#1887
TrevorBurnham wants to merge 1 commit intosmithy-lang:mainfrom
TrevorBurnham:fix/rate-limiter-abort-signal

Conversation

@TrevorBurnham
Copy link
Contributor

Issue #, if available:

Fixes #1758

Description of changes:

When the DefaultRateLimiter is waiting for token bucket capacity via getSendToken, the internal setTimeout delay cannot be cancelled. In environments like AWS Lambda, this means you can't abort a retry wait as the function timeout approaches — the Lambda just fails with a "task timed out" error instead of letting you handle it gracefully.

getSendToken now accepts an optional AbortSignal. When provided, the signal is raced against the delay timer:

  • If the signal is already aborted, the promise rejects immediately with signal.reason.
  • If the signal fires during the wait, the timer is cleared and the promise rejects with signal.reason.
  • If no signal is provided, behavior is unchanged (fully backward compatible).
const rateLimiter = new DefaultRateLimiter();

// Without signal — existing behavior, no change
await rateLimiter.getSendToken();

// With signal — can now abort the wait
const controller = new AbortController();
setTimeout(() => controller.abort(new Error("Lambda timeout approaching")), 5000);
await rateLimiter.getSendToken(controller.signal);

The RateLimiter interface is updated in both @smithy/util-retry and @smithy/middleware-retry to accept the optional parameter.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

When the DefaultRateLimiter is waiting for token bucket capacity, the
setTimeout delay could not be cancelled. This is problematic in
environments like AWS Lambda where you may need to abort the retry
wait as the function timeout approaches.

getSendToken now accepts an optional AbortSignal parameter. When
provided, the signal is raced against the delay timer:
- If the signal is already aborted, the promise rejects immediately
  with the signal's reason.
- If the signal fires during the wait, the timer is cleared and the
  promise rejects with the signal's reason.
- If no signal is provided, behavior is unchanged.

The RateLimiter interface in both util-retry and middleware-retry is
updated to accept the optional parameter.

Fixes smithy-lang#1758
@TrevorBurnham TrevorBurnham requested a review from a team as a code owner February 21, 2026 22:19
@kuhe
Copy link
Contributor

kuhe commented Feb 24, 2026

What is the proposed control mechanism used with a client and a request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When using adaptive retry, the DefaultRateLimiter cannot be aborted by an abort signal when it's waiting

2 participants